#pragma once
#include "../common/util.hpp"
#include "../common/Log.hpp"
#include "mysqlconn.hpp"
#include <mysql/mysql.h>
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <fstream>
#include <cstdlib>
#include <cassert>

// 根据题目list文件，加载所有的题目信息到内存中
// model: 主要用来和数据进行交互，对外提供访问数据的接口

using namespace std;

struct Question
{
    string number; //题目编号，唯一
    string title;  //题目的标题
    string star;   //难度: 简单 中等 困难
    string desc;   //题目的描述
    string header; //题目预设给用户在线编辑器的代码
    string tail;   //题目的测试用例，需要和header拼接，形成完整代码
    int cpu_limit; //题目的时间要求(S)
    int mem_limit; //题目的空间要去(KB)
};

const string oj_questions = "questions";
const string host = "127.0.0.1";
const string user = "zbh";
const string passwd = "123456";
const string db = "oj";
const int port = 3306;

class Model
{
public:
    Model()
    {
        Init();
    }
    void Init()
    {
        // 读取配置文件
        const string jsonpath = "./conf/db_config.json";
        DataBaseConf::DatabaseConfig& config = DataBaseConf::getDatabaseConfig(jsonpath);
        // 进行数据库连接
        conn.mysql_connection(config.host, config.username, config.password, config.dbName);
    }
    bool QueryMySql(const string &sql, vector<Question> *out)
    {
        MYSQL_RES* res = conn.executeSql(sql);
        // 分析结果 这里如果为空就会报错
        int rows = mysql_num_rows(res); //获得行数量
        int cols = mysql_num_fields(res); //获得列数量
        Question q;

        for(int i = 0; i < rows; i++)
        {
            MYSQL_ROW row = mysql_fetch_row(res);
            q.number = row[0];
            q.title = row[1];
            q.star = row[2];
            q.desc = row[3];
            q.header = row[4];
            q.tail = row[5];
            q.cpu_limit = atoi(row[6]);
            q.mem_limit = atoi(row[7]);

            out->push_back(q);
        }
        return true;
    }

    bool GetAllQuestions(vector<Question> *out)
    {
        string sql = "select * from ";
        sql += oj_questions;
        return QueryMySql(sql, out);
    }

    bool GetOneQuestion(const string &number, Question *q)
    {
        bool res = false;
        string sql = "select * from ";
        sql += oj_questions;
        sql += " where id=";
        sql += number;
        vector<Question> result;
        if(QueryMySql(sql, &result))
        {
            if(result.size() == 1)
            {
                *q = result[0];
                res = true;
            }
        }
        return res;
    }
    
    ~Model()
    {}
private:
    mysqlconn conn;
};